package com.pokermind.model.dto;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.math.BigDecimal;

/**
 * 行动记录请求DTO - V4.1增强版
 *
 * V4.1变更：
 * - 增加table_id字段（所有接口统一）
 * - 增加stack_before和pot_before字段（完整的前-中-后状态）
 * - 明确amount字段语义为action_amount（本次行动投入金额）
 *
 * @author PokerMind Team
 */
@JsonIgnoreProperties(ignoreUnknown = true)  // 忽略旧版本客户端的未知字段（如handRecordId）
@JsonPropertyOrder(
    {"tableId", "handId", "playerId", "street", "actionType", "beforeStack", "beforePot", "amount", "afterStack", "afterPot"})
public class ActionRequest {

    /**
     * 桌子ID - 标识具体是哪张桌子
     * 业务含义：table_id + hand_id 唯一标识一个手牌
     * 数据约束：字符串，不能为空
     */
    @JsonProperty("table_id")
    private String tableId;

    /**
     * 手牌ID - 标识具体是哪个手牌的行动
     * 业务含义： - 前端提供的手牌唯一标识(如: TEST_FLOW_H_1759133916856) - 用于关联到具体的游戏局 - 确保行动记录到正确的手牌中
     * 数据约束：字符串，不能为空
     */
    @JsonProperty("hand_id")
    private String handId;

    /**
     * 玩家ID - 前端系统中的玩家唯一标识符 
     * 业务含义： 
     * - 前端提供的玩家唯一标识(如: mp_player_004, btn_player_001) 
     * - 用于关联玩家的历史数据和统计信息
     * - 后端通过此字段查找poker_users表中的用户记录 
     * 数据约束：字符串，不能为空
     */
    @JsonProperty("player_id")
    private String playerId;

    /**
     * 街道 - 行动发生的游戏阶段
     * 业务含义：标识行动发生在哪个游戏阶段（preflop/flop/turn/river）
     * 数据约束：字符串，可选值: "preflop", "flop", "turn", "river"
     */
    @JsonProperty("street")
    private String street;

    /**
     * 行动类型 - 德州扑克中的具体行动
     * 支持的行动类型： 
     * - "fold"  : 弃牌 
     * - "check" : 过牌
     * - "call"  : 跟注 
     * - "raise" : 加注/下注（V4.0统一）
     * - "allin" : 全进
     * 数据约束：字符串枚举
     */
    @JsonProperty("action_type")
    private String actionType;

    /**
     * 行动前筹码 - 玩家执行行动前的筹码余额
     * 业务含义：用于验证行动合法性
     * 数据约束：BigDecimal，不能为负数
     */
    @JsonProperty("before_stack")
    private BigDecimal beforeStack;

    /**
     * 行动前底池 - 执行行动前的底池总金额
     * 业务含义：用于计算和验证行动后的底池
     * 数据约束：BigDecimal
     */
    @JsonProperty("before_pot")
    private BigDecimal beforePot;

    /**
     * 行动金额 - 本次行动投入的筹码数量
     * 业务含义： 
     * - fold/check: 0
     * - call: 跟注金额
     * - raise: 加注金额
     * - allin: 全部筹码
     * 验证公式：before_stack - amount = after_stack
     * 数据约束：BigDecimal，精确到小数点后2位
     */
    private BigDecimal amount;

    /**
     * 行动后筹码 - 玩家执行行动后的筹码余额
     * 业务含义：用于验证行动合法性
     * 计算公式：after_stack = before_stack - amount
     * 数据约束：BigDecimal，不能为负数
     */
    @JsonProperty("after_stack")
    private BigDecimal afterStack;

    /**
     * 行动后底池 - 执行行动后的底池总金额
     * 业务含义：用于验证行动合法性
     * 计算公式：after_pot = before_pot + amount (单人行动时)
     * 数据约束：BigDecimal
     */
    @JsonProperty("after_pot")
    private BigDecimal afterPot;

    /**
     * 思考时间 - 玩家做出决策的耗时(秒)
     * 业务含义： - 玩家从面临决策到执行行动的时间间隔 - 用于分析玩家的决策模式和习惯 - 区分快速决策和深思熟虑的行动 - AI分析中的重要特征之一
     * 统计价值： - 短时间决策通常表示明显的强牌或弱牌 - 长时间决策可能表示边际牌或复杂局面 - 可用于构建玩家的行为画像
     * 数据约束：正整数，单位为秒
     */
    @JsonProperty("think_time_seconds")
    private Integer thinkTimeSeconds;

    /**
     * 是否超时 - 标识玩家是否因时间限制被迫行动（可选）
     * 数据约束：布尔值，默认false
     */
    @JsonProperty("is_timeout")
    private Boolean isTimeout;

    // 默认构造函数
    public ActionRequest() {
    }

    // 构造函数
    public ActionRequest(String tableId, String handId, String playerId, String street, String actionType,
        BigDecimal beforeStack, BigDecimal beforePot, BigDecimal amount,
        BigDecimal afterStack, BigDecimal afterPot) {
        this.tableId = tableId;
        this.handId = handId;
        this.playerId = playerId;
        this.street = street;
        this.actionType = actionType;
        this.beforeStack = beforeStack;
        this.beforePot = beforePot;
        this.amount = amount;
        this.afterStack = afterStack;
        this.afterPot = afterPot;
    }

    // Getters and Setters
    public String getTableId() {
        return tableId;
    }

    public void setTableId(String tableId) {
        this.tableId = tableId;
    }

    public String getHandId() {
        return handId;
    }

    public void setHandId(String handId) {
        this.handId = handId;
    }

    public String getPlayerId() {
        return playerId;
    }

    public void setPlayerId(String playerId) {
        this.playerId = playerId;
    }

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }

    public String getActionType() {
        return actionType;
    }

    public void setActionType(String actionType) {
        this.actionType = actionType;
    }

    public BigDecimal getBeforeStack() {
        return beforeStack;
    }

    public void setBeforeStack(BigDecimal beforeStack) {
        this.beforeStack = beforeStack;
    }

    public BigDecimal getBeforePot() {
        return beforePot;
    }

    public void setBeforePot(BigDecimal beforePot) {
        this.beforePot = beforePot;
    }

    public BigDecimal getAmount() {
        return amount;
    }

    public void setAmount(BigDecimal amount) {
        this.amount = amount;
    }

    public BigDecimal getAfterStack() {
        return afterStack;
    }

    public void setAfterStack(BigDecimal afterStack) {
        this.afterStack = afterStack;
    }

    public BigDecimal getAfterPot() {
        return afterPot;
    }

    public void setAfterPot(BigDecimal afterPot) {
        this.afterPot = afterPot;
    }

    public Integer getThinkTimeSeconds() {
        return thinkTimeSeconds;
    }

    public void setThinkTimeSeconds(Integer thinkTimeSeconds) {
        this.thinkTimeSeconds = thinkTimeSeconds;
    }

    public Boolean getIsTimeout() {
        return isTimeout;
    }

    public void setIsTimeout(Boolean isTimeout) {
        this.isTimeout = isTimeout;
    }

    // 辅助方法 - 日志记录优化

    /**
     * 转换为JSON字符串 - 用于日志记录
     *
     * @return JSON格式的字符串
     */
    public String toJson() {
        try {
            ObjectMapper mapper = new ObjectMapper();
            return mapper.writeValueAsString(this);
        } catch (JsonProcessingException e) {
            // 序列化失败时返回简化格式
            return String.format("{\"tableId\":\"%s\",\"handId\":\"%s\",\"playerId\":\"%s\",\"action\":\"%s\",\"amount\":%s}", 
                tableId, handId, playerId, actionType, amount);
        }
    }

    /**
     * 重写toString方法，返回JSON格式
     */
    @Override
    public String toString() {
        return toJson();
    }
}